package com.tencent.yolov5ncnn;

import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.media.Image;
import android.media.ImageReader;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.util.Size;
import android.view.Surface;

import androidx.annotation.NonNull;

import java.util.ArrayList;

//import android.hardware.camera2.*;
//import android.media.ImageReader;
//
//import android.os.HandlerThread;
//import android.util.Log;
//
//import android.view.Surface;
//
//import java.nio.ByteBuffer;
//import java.util.ArrayList;
//import java.util.Arrays;

public class Camera2Demo2 {

    private static final String TAG = "Camera2Demo2";
//    private static final int IMAGE_CAPTURE_WIDTH = 2340;
//    private static final int IMAGE_CAPTURE_HEIGHT = 1280;
    private static final int IMAGE_CAPTURE_WIDTH = 640;
    private static final int IMAGE_CAPTURE_HEIGHT = 640;
    private static final Size IMAGE_SIZE = new Size(IMAGE_CAPTURE_WIDTH, IMAGE_CAPTURE_HEIGHT);

    private CameraManager mCameraManager;
    private String mCameraId;
    private CameraDevice mCameraDevice;
    private CameraCaptureSession mCaptureSession;
    private ImageReader mImageReader;

    private HandlerThread mBackgroundThread;
    private Handler mBackgroundHandler;

    public Image mImage = null;
    public byte[] mBytes= null;
    public Bitmap mBitmap; //存放图像
    public boolean mBitmapIsUse = false;
    private long mStartTimeMs;


    public Camera2Demo2(CameraManager cameraManager, String cameraId) {
        mCameraManager = cameraManager;
        mCameraId = cameraId;
    }

    public void openCamera() {
        try {
            mCameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, null);
        } catch (CameraAccessException e) {
            Log.e(TAG, "Failed to open camera", e);
        }
    }

    private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice camera) {
            mCameraDevice = camera;
            createCameraCaptureSession();
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) {
            camera.close();
            mCameraDevice = null;
        }

        @Override
        public void onError(@NonNull CameraDevice camera, int error) {
            camera.close();
            mCameraDevice = null;
        }
    };

    private void createCameraCaptureSession() {
//        mImageReader = ImageReader.newInstance(IMAGE_SIZE.getWidth(), IMAGE_SIZE.getHeight(),
//                ImageFormat.JPEG, /*maxImages*/ 2);
        mImageReader = ImageReader.newInstance(IMAGE_SIZE.getWidth(),IMAGE_SIZE.getHeight(),
                ImageFormat.JPEG,  /*maxImages*/ 2);
        mImageReader.setOnImageAvailableListener(imageAvailableListener, mBackgroundHandler);

        try {
            Surface previewSurface = mImageReader.getSurface();
            ArrayList<Surface> outputs = new ArrayList<>();
            outputs.add(previewSurface);

            mCameraDevice.createCaptureSession(outputs,
                    new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(@NonNull CameraCaptureSession session) {
                            mCaptureSession = session;
                            updateCaptureRequest();
                        }

                        @Override
                        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                            Log.w(TAG, "Creating capture session failed");
                        }
                    }, mBackgroundHandler);
        } catch (CameraAccessException e) {
            Log.e(TAG, "Failed to create capture session", e);
        }
    }

    private void updateCaptureRequest() {
        try {
            CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            builder.addTarget(mImageReader.getSurface());
            builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

            mCaptureSession.setRepeatingRequest(builder.build(), null, mBackgroundHandler);
        } catch (CameraAccessException e) {
            Log.e(TAG, "Failed to set repeating request", e);
        }
    }

    private ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader reader) {
            Image image = null;
            try {
                image = reader.acquireLatestImage();
                if (image != null) {
                    try {
                        processImage(image);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            } finally {
                if (image != null) {
                    image.close();
                }
            }
        }
    };

    private void processImage(Image image) throws InterruptedException {
//        // 处理图像数据
//        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
//        byte[] bytes = new byte[buffer.remaining()];
//        buffer.get(bytes);

        // 在这里处理 bytes 数组中的图像数据
        // ...
        saveImageToDisk(image);
        Thread.sleep(5);

        image.close();

        // 统计时间
        if (mStartTimeMs == 0){
            mStartTimeMs = System.currentTimeMillis();
        } else{
            long dt = System.currentTimeMillis() - mStartTimeMs;
            mStartTimeMs = System.currentTimeMillis();
            Log.d(TAG, "获取图像"+ dt + "ms");

        }


    }

    private void saveImageToDisk(Image image) {
        try {
            // 处理图像数据
//            ByteBuffer buffer = image.getPlanes()[0].getBuffer();
//            byte[] bytes = new byte[buffer.remaining()];
//            buffer.get(bytes);
            //mBytes = bytes;

            mBitmap = MyUtils.convertImageToBitmap(image);

//            // 获取外部存储目录
//            File externalStorageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
//
//            // 创建一个文件夹用于保存图片
////            File imageFolder = new File(externalStorageDirectory, "MyAppImagesYolov5");
//            File imageFolder = new File( "/MyAppImagesYolov5");
//            if (!imageFolder.exists()) {
//                imageFolder.mkdirs(); // 创建目录
//            }
//
//            // 创建一个文件名
//            String fileName = "image_" + System.currentTimeMillis() + ".jpg"; // 使用当前时间戳作为文件名的一部分
//
//            // 创建文件
//            File imageFile = new File(imageFolder, fileName);
//
//
//            // 打开输出流
//            FileOutputStream fos = new FileOutputStream(imageFile);
//
//            // 将字节数组写入文件
//            fos.write(bytes);
//
//            // 关闭输出流
//            fos.close();

//            Log.d(TAG, "Image saved to: " + imageFile.getAbsolutePath());
//        } catch (IOException e) {
//            Log.e(TAG, "Error saving image to disk", e);
        } finally {
            // 释放 Image 对象
            image.close();
        }
    }


    public void startBackgroundThread() {
        mBackgroundThread = new HandlerThread("Camera Background");
        mBackgroundThread.start();
        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
    }

    private void stopBackgroundThread() {
        mBackgroundHandler.getLooper().quitSafely();
        try {
            mBackgroundThread.join();
            mBackgroundThread = null;
            mBackgroundHandler = null;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void closeCamera() {
        if (mCaptureSession != null) {
            mCaptureSession.close();
            mCaptureSession = null;
        }
        if (mCameraDevice != null) {
            mCameraDevice.close();
            mCameraDevice = null;
        }
        if (mImageReader != null) {
            mImageReader.close();
            mImageReader = null;
        }
        stopBackgroundThread();
    }





}
